package com.tjetc.utils;

import com.google.common.hash.BloomFilter;
import com.google.common.hash.Funnels;
import com.tjetc.domain.dto.OrderDTO;
import com.tjetc.domain.po.Pass;
import com.tjetc.domain.vo.PassVo;
import com.tjetc.service.PassService;
import jakarta.annotation.PostConstruct;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.stereotype.Component;

import java.util.List;
import java.util.Random;
import java.util.concurrent.TimeUnit;

@Component
@Slf4j
public class BloomFilterInit {

    @Autowired
    private RedisTemplate redisTemplate;


    @Autowired
    private StringRedisTemplate stringRedisTemplate;

    @Autowired
    private PassService passService;

    //1.定义一个常量
    public static final int _1W = 10000;

    //2.定义guava布隆过滤器的初始容量
    public static final int SIZE = 100 * _1W;

    //3.误判率，越小误判的个数越小，占用空间越大，hash函数越多，查的越慢
    public static final double fpp = 0.03; //不传默认值就是0.03

    //4.创建guava布隆过滤器
    public static BloomFilter<Integer> bloomFilter = BloomFilter.create(Funnels.integerFunnel(), SIZE, fpp);

    @PostConstruct
    public void initGuavaBloomFilter() {
        List<Pass> passList = passService.findAll();
        passList.forEach(pass -> {
            /*预热进redis*/
            //redisTemplate.opsForValue().set( pass.getId(), pass.getCount());
            stringRedisTemplate.opsForValue().set("pass:" + pass.getId(), pass.getCount().toString(),60+new Random().nextInt(100), TimeUnit.SECONDS);
            stringRedisTemplate.opsForValue().set("pass2:" + pass.getId(), pass.getCount().toString(),120+new Random().nextInt(100), TimeUnit.SECONDS);
            //布隆过滤器加入白名单数据
            bloomFilter.put(pass.getId());
        });
    }


    /*自研版本*/
    //@PostConstruct
    public void init() {
        List<Pass> passList = passService.findAll();
        passList.forEach(pass -> {
            stringRedisTemplate.opsForValue().set("pass:" + pass.getId(), pass.getCount().toString());
            //1.白名单添加通道
            //2.计算hashValue
            int hashValue = Math.abs(pass.hashCode());
            //3.通过hashValue和2的32次方取余，获得下标坑位
            long index = (long) (hashValue % Math.pow(2, 32)); //redis的string最大长度是512MB字节
            //4.设置redis里面bitmap对应的坑位，将值设为1
            redisTemplate.opsForValue().setBit("whiteListPass", index, true);
        });

    }


    public boolean checkWithBloomFilter(OrderDTO orderDTO) {

        int hashValue = Math.abs(passService.findById(orderDTO.getPassId()).hashCode());
        long index = (long) (hashValue % Math.pow(2, 32));
        return redisTemplate.opsForValue().getBit("whiteListPass", index);

    }




  /*  public boolean checkWithBloomFilter(String checkItem, String key) {
        int hashValue = Math.abs(key.hashCode());
        long index = (long) (hashValue % Math.pow(2, 32));
        boolean existsOk = redisTemplate.opsForValue().getBit(checkItem, index);
        log.info(key + "的下标是否存在{}" + existsOk);
        return existsOk;
    }*/





}
